/*
 * @Author: Await
 * @Date: 2025-05-10 18:35:00
 * @LastEditors: Await
 * @LastEditTime: 2025-05-10 18:35:00
 * @Description: 从3D到2D图表配置转换
 */

import { needsCartesianCoords } from './chartTypeUtils';
import { logDebug } from '../../../utils/chart/commonUtils';

/**
 * 将3D图表配置转换为2D图表配置
 * @param option3D 3D图表配置
 * @returns 2D图表配置
 */
export const fallbackTo2DConfig = (option3D: any): any => {
  if (!option3D) return {};

  // 创建深拷贝，避免修改原对象
  const option2D: any = JSON.parse(JSON.stringify(option3D));

  // 1. 确定目标2D图表类型
  let targetType = 'line';
  if (option3D.type) {
    if (option3D.type.includes('bar')) {
      targetType = 'bar';
    } else if (option3D.type.includes('scatter')) {
      targetType = 'scatter';
    } else if (option3D.type.includes('line')) {
      targetType = 'line';
    }
  }

  // 2. 设置基本配置
  option2D.type = targetType;

  // 3. 移除3D特有配置
  delete option2D.grid3D;
  delete option2D.xAxis3D;
  delete option2D.yAxis3D;
  delete option2D.zAxis3D;
  delete option2D.visualMap;  // 通常用于3D
  delete option2D.viewControl;
  delete option2D.light;
  delete option2D.postProcess;

  // 4. 提取可能的坐标轴标签数据
  let xAxisCategories: any[] = [];

  // 尝试从xAxis3D中提取数据
  if (option3D.xAxis3D && option3D.xAxis3D.data && Array.isArray(option3D.xAxis3D.data)) {
    xAxisCategories = option3D.xAxis3D.data;
  }
  // 尝试从series数据中提取x坐标作为类别
  else if (option3D.series && Array.isArray(option3D.series) && option3D.series.length > 0 &&
    option3D.series[0].data && Array.isArray(option3D.series[0].data)) {

    // 从第一个series的数据中提取x坐标值
    const uniqueXValues = new Set();
    option3D.series[0].data.forEach((item: any) => {
      if (Array.isArray(item) && item.length >= 1) {
        uniqueXValues.add(item[0]);
      }
    });

    if (uniqueXValues.size > 0) {
      xAxisCategories = Array.from(uniqueXValues);
    }
  }

  // 如果没有找到任何类别，使用从0开始的索引
  if (xAxisCategories.length === 0) {
    // 查找一个系列中的数据项数量
    const itemCount = option3D.series &&
      Array.isArray(option3D.series) &&
      option3D.series.length > 0 &&
      option3D.series[0].data &&
      Array.isArray(option3D.series[0].data) ?
      option3D.series[0].data.length : 0;

    // 如果有数据项，为每个数据项创建一个类别
    if (itemCount > 0) {
      xAxisCategories = Array.from({ length: itemCount }, (_, i) => `项目${i + 1}`);
    }
  }

  // 5. 添加2D必要配置
  // 为xAxis添加索引以保证能正确引用
  if (!option2D.xAxis) {
    option2D.xAxis = [{
      type: 'category',
      data: xAxisCategories
    }];
  } else if (!Array.isArray(option2D.xAxis)) {
    // 如果已存在xAxis但不是数组，转换为数组
    option2D.xAxis = [option2D.xAxis];
  }

  // 为yAxis添加索引以保证能正确引用
  if (!option2D.yAxis) {
    option2D.yAxis = [{
      type: 'value'
    }];
  } else if (!Array.isArray(option2D.yAxis)) {
    // 如果已存在yAxis但不是数组，转换为数组
    option2D.yAxis = [option2D.yAxis];
  }
  
  // 确保坐标轴数组至少有一个元素
  if (Array.isArray(option2D.xAxis) && option2D.xAxis.length === 0) {
    option2D.xAxis.push({
      type: 'category',
      data: xAxisCategories
    });
  }
  
  if (Array.isArray(option2D.yAxis) && option2D.yAxis.length === 0) {
    option2D.yAxis.push({
      type: 'value'
    });
  }

  // 确保有grid配置
  if (!option2D.grid) {
    option2D.grid = {
      containLabel: true
    };
  }

  // 6. 转换series数据
  if (option2D.series && Array.isArray(option2D.series)) {
    option2D.series = option2D.series.map((series: any) => {
      // 新的2D系列
      const newSeries: any = {
        type: targetType,
        name: series.name || '数据系列',
        data: []
      };

      // 保留原始样式设置
      if (series.itemStyle) newSeries.itemStyle = series.itemStyle;
      if (series.lineStyle) newSeries.lineStyle = series.lineStyle;
      if (series.label) newSeries.label = series.label;
      if (series.emphasis) newSeries.emphasis = series.emphasis;

      // 转换数据
      if (series.data && Array.isArray(series.data)) {
        try {
          // 转换数据格式
          if (targetType === 'bar' || targetType === 'line') {
            // 对于bar和line，我们使用z值(第三个值)
            newSeries.data = series.data.map((item: any, index: number) => {
              if (Array.isArray(item) && item.length >= 3) {
                return item[2]; // 提取z值
              } else if (Array.isArray(item) && item.length >= 1) {
                return item[0]; // 至少提取一个值
              } else if (typeof item === 'object' && item !== null && item.value) {
                return Array.isArray(item.value) ? item.value[2] || 0 : item.value;
              } else if (typeof item === 'number') {
                return item; // 如果是数字，直接使用
              } else {
                logDebug(`从3D转换数据项 ${index} 时使用0值，原数据:`, item);
                return 0; // 默认值
              }
            });
          } else if (targetType === 'scatter') {
            // 对于scatter，我们使用[x, y]值，忽略z
            newSeries.data = series.data.map((item: any, index: number) => {
              if (Array.isArray(item) && item.length >= 2) {
                return [item[0], item[1]]; // 提取x, y值
              } else if (Array.isArray(item) && item.length === 1) {
                return [index, item[0]]; // 使用索引作为x，值作为y
              } else if (typeof item === 'object' && item !== null) {
                if (Array.isArray(item.value) && item.value.length >= 2) {
                  return [item.value[0], item.value[1]];
                } else {
                  return [index, item.value || 0];
                }
              } else if (typeof item === 'number') {
                return [index, item]; // 如果是数字，索引作为x，值作为y
              } else {
                logDebug(`转换scatter数据项 ${index} 时使用[${index}, 0]，原数据:`, item);
                return [index, 0]; // 默认值
              }
            });
          }
        } catch (error) {
          logDebug('转换3D数据到2D时出错，使用空数组:', error);
          newSeries.data = [];
        }
      } else {
        // 没有有效数据，使用空数组
        newSeries.data = [];
      }

      return newSeries;
    });
  } else {
    // 没有系列，创建一个空系列
    option2D.series = [{
      type: targetType,
      data: []
    }];
  }

  // 确保至少有一个系列
  if (!option2D.series || !Array.isArray(option2D.series) || option2D.series.length === 0) {
    option2D.series = [{
      type: targetType,
      data: []
    }];
  }

  logDebug('从3D转换到2D的最终配置:', option2D);
  return option2D;
};

export default fallbackTo2DConfig;